package com.yujiahao.bigdata.rdd.action

import org.apache.spark.rdd.RDD
import org.apache.spark.{SparkConf, SparkContext}
/**

  TODO 序列化
    1、什么时候考虑序列化？
      1）saveAsObjectFile：内存的数据保到文件中；
      2）网络数据传输：需要对象进行序列化
    2、Spark将分布式的操作从代码中剥离出来，进行了封装，减低了开发的难度，这也是为什么将RDD的方法称之为算子的原因
 TODO 算子的【内部】逻辑实现其实是在【Executor】端执行的。
 TODO 算子的【外部】逻辑其实是在【Driver】端执行的。
  如果在算子的内部使用了外部的数据，那么数据需要从Driver端拉取到Executor端
  如果在算子的内部使用了外部的数据，那么数据就需要Driver端拉取到Executor端，这就需要将数据通过网络进行传输化，如果不序列化就会发生错误

*/

object Spark01_Action_Closure {
  def main(args: Array[String]): Unit = {
    //TODO 1、获得Spark环境的连接
    // 参数解读：setAppName("当前执行程序的名字").setMaster("当前的环境")
    // 分布式环境的基本架构为 主 - 从
    val conf: SparkConf = new SparkConf().setAppName("WordCount").setMaster("local")
    val sc: SparkContext = new SparkContext(conf)
    //TODO 3、业务逻辑
    val user: User = new User()

    val rdd: RDD[Int] = sc.makeRDD(List(1, 2, 3, 4), 2)

    //    如果不序列化就会报错：SparkException: Task not serializable
    //    User not serializable

    rdd.foreach(

      num => {
        println((user.age + num))
      }
    )
    //TODO 2、关闭Spark环境的连接
    sc.stop()

  }

  //序列化的类要进行序列化，直接继承可以
  //class User extends Serializable {
  //或者直接使用样例类，因为它已经进行了序列化
  case class User() {
    var age: Int = 30
  }
}
